<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <div>
            <div></div>
            给定 n 个非负整数表示每个宽度为 1 的柱子的高度图，计算按此排列的柱子，下雨之后能接多少雨水。
            <div>输入：height = [0,1,0,2,1,0,1,3,2,1,2,1] 输出：6 解释：上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图，在这种情况下，可以接 6 个单位的雨水（蓝色部分表示雨水）。</div>
            <div>示例 2： 输入：height = [4,2,0,3,2,5] 输出：9 来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/trapping-rain-water 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。</div>
            <br />
            来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/4sum 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
        </div>
        <script>
            let height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]; // 6
            let height1 = [4, 2, 0, 3, 2, 5]; // 9

            /**
             * 暴力解法
             * O(n^2)
             * O(1)
             * @param {number[]} height
             * @return {number}
             */
            var trap = function (height) {
                let res = 0;
                for (var i = 1; i < height.length - 1; i++) {
                    let max_l = 0;
                    let max_r = 0;
                    for (var j = i; j < height.length; j++) {
                        max_r = Math.max(height[j], max_r);
                    }
                    for (var j = i; j >= 0; j--) {
                        max_l = Math.max(height[j], max_l);
                    }
                    curH = Math.min(max_l, max_r) - height[i];
                    res += curH;
                }
                return res;
            };

            /**
             * 动态规划
             * O(N)
             * O(N)
             * @param {number[]} height
             * @return {number}
             */
            var trap2 = function (height) {
                console.log(height);
                let res = 0;
                let len = height.length;
                let lMaxList = new Array(len);
                let rMaxList = new Array(len);

                lMaxList[0] = height[0];
                rMaxList[len - 1] = height[len - 1];

                for (let index = 1; index < len; index++) {
                    lMaxList[index] = Math.max(height[index], lMaxList[index - 1]);
                }
                console.log(lMaxList);

                for (let index = len - 2; index >= 0; index--) {
                    rMaxList[index] = Math.max(height[index], rMaxList[index + 1]);
                }
                console.log(rMaxList);

                for (let index = 1; index < len - 1; index++) {
                    res += Math.min(lMaxList[index], rMaxList[index]) - height[index];
                }

                return res;
            };

            /**
             * 双指针
             * O(N)
             * O(1)
             * @param {number[]} height
             * @return {number}
             */
            var trap3 = function (height) {
                console.log(height);
                let res = 0;
                let len = height.length;

                let left = 0;
                let right = len - 1;

                let l_max = height[0];
                let r_max = height[len - 1];

                // 水从两边流走开始算起 哪边低往那边流走
                // 哪边低就去先掉哪边，往中间靠
                while (left <= right) {
                    console.log('while ~ ', left, right);
                    l_max = Math.max(l_max, height[left]);
                    r_max = Math.max(r_max, height[right]);
                    console.log(`       l_max: ${l_max}  r_max: ${r_max} `);
                    if (l_max < r_max) {
                        console.log(`       ==> left[${left}]: ${l_max - height[left]}`);
                        res += l_max - height[left];
                        left++;
                    } else {
                        console.log(`       ==> right[${left}]: ${r_max - height[right]}`);
                        res += r_max - height[right];
                        right--;
                    }
                }

                return res;
            };

            console.log(trap3(height));
            console.log(trap3(height1));
        </script>
    </body>
</html>
